﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Services.Client;
using System.Linq;

namespace Songhay.Silverlight.BiggestBox.IndexPart.ViewModels
{
    using NetflixServiceReference;
    using ServiceContext;
    using Songhay.Extensions;
    using Songhay.Mvvm.ViewModels;

    /// <summary>
    /// Defines the Netflix View Model
    /// </summary>
    /// See “Consuming OData with MVVM for Windows Phone”
    /// [http://code.msdn.microsoft.com/Consuming-OData-with-MVVM-66540635/sourcecode?fileId=41693&pathId=716529201]
    /// <remarks>
    /// </remarks>
    public class NetflixViewModel : ViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="NetflixViewModel"/> class.
        /// </summary>
        /// <remarks>
        /// For details, see
        /// “How to: Implement Property Change Notification”
        /// http://msdn.microsoft.com/en-us/library/ms743695.aspx
        /// A sample <c>set</c> block:
        /// <code>
        /// set
        /// {
        /// _myProperty = value;
        /// OnPropertyChanged("MyProperty");
        /// }
        /// </code>
        /// </remarks>
        public NetflixViewModel()
        {
            if(base.IsInDesignMode)
            {
                #region design-time data:

                this.NetflixGenres = new ObservableCollection<Genre>
                (
                    new List<Genre>
                    {
                        new Genre { Name = "Genre 1" },
                        new Genre { Name = "Genre 2" },
                        new Genre { Name = "Genre 3" },
                    }
                );

                var boxart = new BoxArt
                {
                    SmallUrl = "/Songhay.Silverlight.BiggestBox.IndexPart;Component/Bitmaps/NetflixDummyImage.png"
                };

                this.NetflixTitles = new ObservableCollection<Title>(new ObservableCollection<Title>
                {
                    new Title { Id = "ID01-1", BoxArt = boxart, Name = "Title One", Rating = "PG-13", ReleaseYear = 1983, ShortName = "Title1-1" },
                    new Title { Id = "ID02-1", BoxArt = boxart, Name = "Title Two", Rating = "NR", ReleaseYear = 1898, ShortName = "Title2-1" },
                    new Title { Id = "ID03-1", BoxArt = boxart, Name = "Title Three", Rating = "NR", ReleaseYear = 1933, ShortName = "Title3-1" },
                    new Title { Id = "ID04-1", BoxArt = boxart, Name = "Title Four", Rating = "R", ReleaseYear = 2001, ShortName = "Title4-1" },
                    new Title { Id = "ID05-1", BoxArt = boxart, Name = "Title Five", Rating = "G", ReleaseYear = 1997, ShortName = "Title5-1" }
                });

                #endregion
            }
            else
            {
                this.IsLoadingGenres = true;
                NetflixContext.LoadGenres(new Action<object, LoadCompletedEventArgs>((s, args) =>
                {
                    this.IsLoadingGenres = false;
                    var collection = NetflixContext.NetflixGenres.ToObservableCollection<Genre>();
                    this.NetflixGenres = collection;
                }));
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is loading genres.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is loading genres; otherwise, <c>false</c>.
        /// </value>
        public bool IsLoadingGenres
        {
            get { return this._isLoadingGenres; }
            set
            {
                this._isLoadingGenres = value;
                base.RaisePropertyChanged("IsLoadingGenres");
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is loading titles.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is loading titles; otherwise, <c>false</c>.
        /// </value>
        public bool IsLoadingTitles
        {
            get { return this._isLoadingTitles; }
            set
            {
                this._isLoadingTitles = value;
                base.RaisePropertyChanged("IsLoadingTitles");
            }
        }

        /// <summary>
        /// Gets or sets the Netflix genres.
        /// </summary>
        /// <value>The Netflix genres.</value>
        public ObservableCollection<Genre> NetflixGenres
        {
            get { return this._netflixGenres; }
            set
            {
                this._netflixGenres = value;
                if(this._netflixGenres == null) return;

                base.RaisePropertyChanged("NetflixGenres");
            }
        }

        /// <summary>
        /// Gets or sets the Netflix selected genre.
        /// </summary>
        /// <value>The Netflix selected genre.</value>
        public Genre NetflixSelectedGenre
        {
            get { return this._selectedGenre; }
            set
            {
                this._selectedGenre = value;

                base.RaisePropertyChanged("NetflixSelectedGenre");

                if((this._selectedGenre == null) ||
                    (this._selectedGenre.Titles == null)) return;

                var titles = this._selectedGenre.Titles;
                titles.LoadCompleted += (s, args) =>
                {
                    this.IsLoadingTitles = false;
                    if((titles.Continuation != null) && (titles.Count() < 250))
                    {
                        titles.LoadNextPartialSetAsync();
                    }

                    this.NetflixTitles = new ObservableCollection<Title>(titles.Where(i => i.BoxArt != null));
                };
                this.IsLoadingTitles = true;
                titles.LoadAsync();
            }
        }

        /// <summary>
        /// Gets the Netflix titles.
        /// </summary>
        /// <value>The Netflix titles.</value>
        public ObservableCollection<Title> NetflixTitles
        {
            get { return this._netflixTitles; }
            set
            {
                this._netflixTitles = value;
                base.RaisePropertyChanged("NetflixTitles");
            }
        }

        ObservableCollection<Genre> _netflixGenres;
        ObservableCollection<Title> _netflixTitles;
        bool _isLoadingGenres;
        bool _isLoadingTitles;
        Genre _selectedGenre;
    }
}
